package gvjclient;

/*
	Copyright 2010 Arpit Sud
	This file is part of gv-jclient. (http://code.google.com/p/gv-jclient/)
	gv-jclient is an Unofficial Java client for Google Voice.
	
    gv-jclient is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    gv-jclient is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with gv-jclient.  If not, see <http://www.gnu.org/licenses/>.
*/

import gvjava.org.json.JSONException;
import gvjclient.types.Account;
import gvjclient.types.Contact;
import gvjclient.ui.GVJclientUI;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;

import com.techventus.server.voice.Voice;
import com.techventus.server.voice.datatypes.AllSettings;
import com.techventus.server.voice.datatypes.Phone;


public class GVJclient
{
	private Voice voice;
	private Account account;
	private Contact[] contacts;
	private AllSettings settings;
	private boolean loggedIn = false;
	
	public GVJclient(Account account)
	{
		this.account = account;
		this.readContacts();
	}

	private void readContacts()
	{
		String fileName = System.getProperty("user.home") + File.separator +
					".gvjclient" + File.separator + "contacts.list";
		Contact contact;
		ArrayList<Contact> arrayList = new ArrayList<Contact>();
		String temp;
		String[] tempArray;
		
		Scanner scanner = null;
		try 
		{
			scanner = new Scanner(new File(fileName));
			while(scanner.hasNextLine())
			{
				temp = scanner.nextLine();
				if(temp.matches("([\\w-@' ]+)%([\\d+]+)"))
				{
					tempArray = temp.split("%");
					contact = new Contact(tempArray[0],tempArray[1]);
					arrayList.add(contact);
				}
			}
		} catch (IllegalStateException e) {
			
		} catch (FileNotFoundException e) {
			System.out.println("Contacts File Not Found!");
		}
		finally {
			if(scanner != null)
				scanner.close();
			this.contacts = (Contact[])arrayList.toArray(new Contact[arrayList.size()]);			
		}
	}
	
	public void login(String username, String password) throws IOException
	{
		voice = new Voice(username,password);
		this.fetchSettings();
		//throw new IOException();
	}
	
	public void initialLogin()
	{
		/* Code obtained from
		 * http://bugs.sun.com./bugdatabase/view_bug.do?bug_id=5018574
		 */
		String userid;
		JPanel panel;
		JLabel label;
		JPasswordField passwordText;
		String password;
		panel = new JPanel();
		panel.setLayout(new FlowLayout());
		userid = this.getAccountUsername();
		label = new JLabel("Please enter password for " + userid + " :");
		passwordText = new JPasswordField(20);
		panel.add(label);
		panel.add(passwordText);
		panel.setPreferredSize(new Dimension(400,60));
		
		passwordText.addHierarchyListener(new HierarchyListener() {
	        public void hierarchyChanged(HierarchyEvent e) {
	            final Component c = e.getComponent();
	            if (c.isShowing() && (e.getChangeFlags() &
	                HierarchyEvent.SHOWING_CHANGED) != 0) {
	                Window toplevel = SwingUtilities.getWindowAncestor(c);
	                toplevel.addWindowFocusListener(new WindowAdapter() {
	                    public void windowGainedFocus(WindowEvent e) {
	                        c.requestFocus();
	                    }
	                });
	            }
	        }
	    });

		int result = JOptionPane.showConfirmDialog(GVJclientUI.get_instance(), panel,
					"Password:",JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE);
		if ( result == JOptionPane.OK_OPTION)
		{
			try
			{
				password = passwordText.getText();
				this.login(userid, password);
				loggedIn = true;
			}catch(IOException e)
			{
				JOptionPane.showMessageDialog(GVJclientUI.get_instance(),"Error logging in as: " + userid + 
						"\nInvalid username/password combination or communication error.", "Login - Error", JOptionPane.ERROR_MESSAGE);
			}
		} else
		{
			System.out.println("User Cancelled!");
		}
	}
	public void logout() throws IOException
	{
		String result = voice.logout();
		loggedIn = false;
		System.out.println(result);
	}
	
	public String call(String source, String destination , String type) throws IOException
	{
		String result = voice.call(source,destination, type);
		return result;
	}
	
	public String sendSMS(String destination, String text) throws IOException
	{
		String result = voice.sendSMS(destination, text);
		return result;
	}
	
	public Contact[] getContacts()
	{
		return contacts;
	}
	
	public Phone[] getPhones()
	{
		if ( this.loggedIn == true )
			return settings.getPhones();
		else
			return null; 
	}
	
	private void fetchSettings() 
	{
		try 
		{
			settings = voice.getSettings(false);
		}catch(IOException e)
		{
			
		} catch (JSONException e)
		{
			
		}
	}

	public String getAccountName() 
	{
		return account.getNickname();
	}
	
	public String getAccountUsername()
	{
		return account.getUserId();
	}

	public Account getAccount()
	{
		return this.account;
	}
	
	public String toString()
	{
		return this.getAccountName();
	}
	
	public boolean isLoggedIn()
	{
		return loggedIn;
	}
	
	public String getPrimaryDID()
	{
		if (this.isLoggedIn())
			return this.settings.getSettings().getPrimaryDid();
		else
			return null;
	}
}